package br.iars.web.bean;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import br.iars.web.util.MessageResource;

public class GenericBean implements Serializable {

	private static final long serialVersionUID = 7589855522907620661L;

	protected static final String MESSAGE_FIELD_NAME = "messages";

	/**
	 * Get an instance of HttpSession.
	 * 
	 * @return The instance of HttpSession.
	 */
	protected HttpSession getHttpSession() {
		return (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
	}

	/**
	 * Get an instance of HttpSession.
	 * 
	 * @return The instance of HttpSession.
	 */
	protected HttpServletRequest getHttpRequest() {
		return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
	}

	/**
	 * Get an instance of a session bean.
	 * 
	 * @param bean
	 *            Bean name.
	 * @return The instance of bean.
	 */
	protected static Object getBeanFromSession(String bean) {
		return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(bean);
	}

	/**
	 * Get an instance of a request bean.
	 * 
	 * @param bean
	 *            Bean name.
	 * @return The instance of bean.
	 */
	protected static Object getBeanFromRequest(String bean) {
		return FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(bean);
	}

	/**
	 * Add a message of a type into the faces context.
	 * 
	 * @param field
	 *            Name of component that show the messages.
	 * @param messageKey
	 *            Key of the message.
	 * @param severity
	 *            Message type.
	 * @param messageArgs
	 *            Parameters of the message.
	 */
	private void addMessage(String field, String messageKey, String messageTitle, Severity severity, Object... messageArgs) {
		FacesMessage facesMessage = new FacesMessage();
		facesMessage.setSeverity(severity);
		facesMessage.setSummary(MessageResource.get(messageTitle, messageArgs));
		facesMessage.setDetail(MessageResource.get(messageKey, messageArgs));
		FacesContext.getCurrentInstance().addMessage(field, facesMessage);
	}

	/**
	 * Add a error message into the FacesContext.
	 * 
	 * @param field
	 *            Name of component that show the messages.
	 * @param messageKey
	 *            Key of the message.
	 * @param messageArgs
	 *            Parameters of the message.
	 */
	protected void addMessageError(String field, String messageKey, Object... messageArgs) {
		addMessage(field, messageKey, "message_error", FacesMessage.SEVERITY_ERROR, messageArgs);
	}

	/**
	 * Add a list of error message with parameters into the FacesContext.
	 * 
	 * @param field
	 *            Name of component that show the messages
	 * @param messages
	 *            List of key of messages.
	 */
	protected void addMessagesError(String field, List<String> messages) {
		for (String message : messages) {
			addMessageError(field, message);
		}
	}

	/**
	 * Add a list of error message with parameters into the FacesContext.
	 * 
	 * @param field
	 *            Name of component that show the messages
	 * @param messages
	 *            Map of key of messages and parameters.
	 */
	protected void addMessagesError(String field, Map<String, Object> messages) {
		for (String message : messages.keySet()) {
			if (messages.get(message) instanceof Object[]) {
				addMessageError(field, message, (Object[]) messages.get(message));
			} else {
				addMessageError(field, message, messages.get(message));
			}
		}
	}

	/**
	 * Add a success message into the FacesContext.
	 * 
	 * @param field
	 *            Name of component that show the messages.
	 * @param messageKey
	 *            Key of the message.
	 * @param messageArgs
	 *            Parameters of the message.
	 */
	protected void addMessageSuccess(String field, String messageKey, Object... messageArgs) {
		addMessage(field, messageKey, "message_success", FacesMessage.SEVERITY_INFO, messageArgs);
	}

	/**
	 * Add a list of success message with parameters into the FacesContext.
	 * 
	 * @param field
	 *            Name of component that show the messages
	 * @param messages
	 *            List of key of messages.
	 */
	protected void addMessagesSuccess(String field, List<String> messages) {
		for (String message : messages) {
			addMessageSuccess(field, message);
		}
	}

	/**
	 * Add a list of success message with parameters into the FacesContext.
	 * 
	 * @param field
	 *            Name of component that show the messages
	 * @param messages
	 *            Map of key of messages and parameters.
	 */
	protected void addMessagesSuccess(String field, Map<String, Object> messages) {
		for (String message : messages.keySet()) {
			if (messages.get(message) instanceof Object[]) {
				addMessageSuccess(field, message, (Object[]) messages.get(message));
			} else {
				addMessageSuccess(field, message, messages.get(message));
			}
		}
	}

	/**
	 * Remove messages of the FacesContext.
	 */
	protected void removeMessages() {
		Iterator<FacesMessage> iterator = FacesContext.getCurrentInstance().getMessages();
		while (iterator.hasNext()) {
			iterator.remove();
		}
	}

}